package com.iteaj.iot.client.modbus.message;

import com.iteaj.iot.Message;
import com.iteaj.iot.client.modbus.ModbusCode;
import com.iteaj.iot.utils.ByteUtil;

import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @see ModbusTcpBody
 */
public class ModbusTcpHeader implements Message.MessageHead{

    private short messageId;
    private short protocolId = 0x00; // 协议标识 占2byte, 0x00 标识modbus协议

    private short length; // unitId + RTU长度 占2byte
    private byte unitId; // 单元标识 占1byte (从机地址)

    private byte[] message;

    protected ModbusTcpHeader() {}

    /**
     * 构建请求头报文头
     * @param unitId 设备地址
     * @param messageId 递增的报文id
     * @param rtuLength rtu长度
     * @return
     */
    public static ModbusTcpHeader buildRequestHeader(byte unitId, short messageId, short rtuLength) {
        ModbusTcpHeader modbusTcpHeader = new ModbusTcpHeader();
        modbusTcpHeader.messageId = messageId;
        modbusTcpHeader.length = (short) (1+ rtuLength); // unitId(1) + rtuLength
        modbusTcpHeader.unitId = unitId;

        modbusTcpHeader.message = new byte[2 + 2 + 2 + 1]; // messageId(2) + protocolId(2) + length(2) + unitId(1)
        ByteUtil.addBytes(modbusTcpHeader.message, ByteUtil.shortToBytes(messageId), 0); // transactionId
        ByteUtil.addBytes(modbusTcpHeader.message, ByteUtil.shortToBytes(modbusTcpHeader.protocolId), 2); // protocolId
        ByteUtil.addBytes(modbusTcpHeader.message, ByteUtil.shortToBytes(modbusTcpHeader.length), 4); // length
        ByteUtil.addBytes(modbusTcpHeader.message, new byte[]{modbusTcpHeader.unitId}, 6); // unitId(deviceSn)

        return modbusTcpHeader;
    }

    public static ModbusTcpHeader buildResponseHeader(byte[] message) {
        short messageId = ByteUtil.bytesToShort(message, 0);
        short length = ByteUtil.bytesToShort(message, 4);
        byte deviceId = ByteUtil.getByte(message, 6);

        ModbusTcpHeader header = new ModbusTcpHeader();
        header.message = ByteUtil.subBytes(message, 0, 7);
        header.unitId = deviceId;
        header.length = length;
        header.messageId = messageId;

        return header;
    }

    @Override
    public String getEquipCode() {
        return String.valueOf(this.unitId);
    }

    @Override
    public String getMessageId() {
        return this.messageId + "";
    }

    @Override
    public <T> T getType() {
        throw new UnsupportedOperationException("不支持的操作");
    }

    public byte getUnitId() {
        return unitId;
    }

    public void setUnitId(byte unitId) {
        this.unitId = unitId;
    }

    @Override
    public byte[] getMessage() {
        return this.message;
    }

    public void setMessage(byte[] message) {
        this.message = message;
    }

    public short getProtocolId() {
        return protocolId;
    }

    public void setProtocolId(short protocolId) {
        this.protocolId = protocolId;
    }

    @Override
    public String toString() {
        return "ModbusTcpHeader{" +
                "messageId=" + messageId +
                ", protocolId=" + protocolId +
                ", length=" + length +
                ", unitId=" + unitId +
                ", message=" + ByteUtil.bytesToHex(message) +
                '}';
    }
}
